using UnityEngine;
using DG.Tweening;
using System;

/// <summary>
/// ׷���ƶ�����
/// </summary>
public class HomingMovement : IMovementStrategy
{
    /// <summary>
    ///���ת��Ƕȣ���/�룩
    /// </summary>
    private readonly float m_MaxTurnAngle;
    /// <summary>
    /// ����ƶ��ٶ�
    /// </summary>
    private readonly float m_MaxSpeed;
    /// <summary>
    /// ���ٶ�
    /// </summary>
    private readonly float m_Acceleration;

    public HomingMovement(float maxTurnAngle = 180f, float maxSpeed = 10f, float acceleration = 5f)
    {
        m_MaxTurnAngle = maxTurnAngle;
        m_MaxSpeed = maxSpeed;
        m_Acceleration = acceleration;
    }

    public void Move(GameObject bullet, Vector3 start, Vector3 end, float duration, Action callback)
    {
        // �����ӵ���ʼλ��
        bullet.transform.position = start;

        // ��ȡĿ������������Ŀ�������һ��"Player"��ǩ��
        GameObject target = GameObject.FindGameObjectWithTag("Player");

        if (target == null)
        {
            // ����Ҳ���Ŀ�꣬���˵������ƶ�
            Logger.LogWarning("Homing target not found. Falling back to linear movement.");
            new LinearMovement().Move(bullet, start, end, duration, callback);
            return;
        }

        // ����׷������
        Sequence homingSequence = DOTween.Sequence();

        // ��ʼ�ٶ�
        Vector3 velocity = (end - start).normalized * m_MaxSpeed;

        // ���Ӹ��»ص���ÿ֡�����ӵ�λ��
        homingSequence.AppendCallback(() => {
            if (bullet == null || target == null)
                return;

            // ����ָ��Ŀ��ķ���
            Vector3 targetDirection = (target.transform.position - bullet.transform.position).normalized;

            // ���㵱ǰ������Ŀ�귽��֮��ĽǶȲ�
            float angle = Vector3.Angle(velocity.normalized, targetDirection);

            // �������������ת�Ƕ�
            float maxTurnThisFrame = m_MaxTurnAngle * Time.deltaTime;

            // ������ת�Ƕ�
            float actualTurn = Mathf.Min(angle, maxTurnThisFrame);

            // ������ת��
            Vector3 rotationAxis = Vector3.Cross(velocity.normalized, targetDirection).normalized;

            // Ӧ����ת
            Quaternion rotation = Quaternion.AngleAxis(actualTurn, rotationAxis);
            velocity = rotation * velocity;

            // Ӧ�ü��ٶ�
            velocity = Vector3.ClampMagnitude(velocity + velocity.normalized * m_Acceleration * Time.deltaTime, m_MaxSpeed);

            // ����λ��
            bullet.transform.position += velocity * Time.deltaTime;
        });

        // ���ó���ʱ��
        homingSequence.SetLoops(-1); // ����ѭ��ֱ���ֶ�ֹͣ

        // ���ӽ�������������ʱ�������
        homingSequence.AppendInterval(duration)
            .OnComplete(() => {
                homingSequence.Kill();
                callback?.Invoke();
            });

        // ������ײ��⣨��ѡ��
        homingSequence.OnKill(() => {
            // ���������������ײ����߼�
        });
    }
}
